<template>
    <Card title="基本信息">
        <el-form ref="formRef" :model="formData" :rules="rules" label-width="auto" scroll-to-error>
            <el-form-item v-if="formData.id" :label="formData.id ? '商品id' : ''">
                <el-input v-model="formData.goodsNo" disabled />
            </el-form-item>
            <el-form-item label="商品图片" prop="materialSrc" required class="form_item_upload_img">
                <draggable
                    class="upload_list"
                    v-model="formData.materialSrc"
                    draggable=".draggable"
                    item-key="index"
                    animation="300"
                    chosenClass="chosen">
                    <template #item="{ element }">
                        <div :class="element.class">
                            <ShowImg
                                v-if="element.class === 'draggable'"
                                :element="element"
                                @setCover="onSetCover"
                                @delete="onDelete" />
                            <ImgUpload
                                v-if="element.class === 'upload' && formData.materialSrc.length < 10"
                                @change="onUploadChange" />
                        </div>
                    </template>
                </draggable>
                <div class="desc">建议尺寸800x800像素，最多添加9张，可拖拽调整展示顺序。</div>
            </el-form-item>
            <el-form-item label="商品名称" prop="goodsName">
                <el-input
                    v-model.trim="formData.goodsName"
                    maxlength="50"
                    show-word-limit
                    placeholder="请输入商品名称，不超过50个字" />
            </el-form-item>
            <el-form-item label="商品类目">
                <el-tree-select
                    v-model="formData.classId"
                    :cacheData="formData.classCacheData"
                    filterable
                    lazy
                    clearable
                    :check-strictly="false"
                    placeholder="请选择商品类目"
                    @visible-change="classVisibleChangeHandle"
                    @node-expand="classNodeExpandHandle"
                    :load="classLoadHandle"
                    :props="classTreeProps" />
            </el-form-item>
            <el-form-item label="商品分组">
                <el-tree-select
                    v-model="formData.category"
                    :cacheData="formData.categoryCacheData"
                    ref="categoryTreeSelectRef"
                    filterable
                    lazy
                    clearable
                    node-key="id"
                    multiple
                    :check-strictly="false"
                    placeholder="请选择商品分组"
                    @visible-change="categoryVisibleChangeHandle"
                    @node-expand="categoryNodeExpandHandle"
                    :load="categoryLoadHandle"
                    :props="categoryTreeProps" />
            </el-form-item>
            <el-form-item label="外部SPU编码" prop="erpSpuId">
                <el-input
                    v-model.trim="formData.erpSpuId"
                    maxlength="50"
                    show-word-limit
                    placeholder="非必填，用于商家ERP、OMS等外部系统" />
            </el-form-item>
        </el-form>
    </Card>
</template>

<script setup>
import Card from './card.vue';
import ImgUpload from './imgUpload.vue';
import ShowImg from './showImg.vue';
import { inputFormatter } from '@/commons/utils.js';
import {
    getGoodsClassListHook,
    getGoodsClassChildListHook,
    getGoodsCategoryListHook,
    getGoodsCategoryChildListHook
} from '@/hooks/goods';
import draggable from 'vuedraggable';
import { reactive, ref } from 'vue';

const formRef = ref(null);
const formData = reactive({
    id: '',
    goodsNo: '',
    goodsName: '',
    category: [],
    classId: '',
    materialSrc: [{ index: 9, url: '', class: 'upload' }],
    erpSpuId: '',
    // 仅用于数据回显
    classCacheData: [],
    // 仅用于数据回显
    categoryCacheData: []
});
// 图片上传
const onUploadChange = v => {
    const index = formData.materialSrc.length - 1;
    formData.materialSrc.splice(index, 0, { index: index, isCover: index === 0, url: v, class: 'draggable' });
    formRef.value.validateField('materialSrc');
};

const onSetCover = v => {
    formData.materialSrc.forEach(item => {
        item.isCover = false;
        if (item.index === v.index) {
            item.isCover = true;
        }
    });
};
const onDelete = v => {
    formData.materialSrc.splice(v.index, 1);
    formData.masterUrl = '';
    formData.materialSrc.forEach((item, index) => {
        if (item.class != 'upload') item.index = index;
    });
    if (v.isCover) {
        formData.materialSrc.forEach((item, index) => {
            if (item.class != 'upload') {
                item.isCover = index === 0;
                item.index = index;
            }
        });
    }
};

const materialSrcValidator = (rule, value, callback) => {
    if (value.length < 2) {
        callback(new Error('请上传商品图片'));
    } else {
        callback();
    }
};

const rules = reactive({
    materialSrc: [{ validator: materialSrcValidator, trigger: 'change' }],
    goodsName: [
        { required: true, message: '请输入商品名称', trigger: ['blur', 'change'] },
        { min: 1, max: 50, message: '商品名称不可超过50个字符', trigger: 'blur' }
    ]
});

const classTreeProps = {
    value: 'id',
    label: 'name',
    children: 'children',
    isLeaf: 'hasChildren',
    disabled: 'disabled'
};
const categoryTreeProps = {
    value: 'id',
    label: 'categoryName',
    children: 'children',
    isLeaf: 'hasChildren',
    disabled: 'disabled'
};
/******************************* 商品类目-start  *******************************/
const classChildRequestSuccess = {};
const classChildParams = {
    classIds: []
};
let classNode = null;
let classResolve = null;
let classRequestFlag = true;
const classLoadHandle = async (node, resolve) => {
    if (classRequestFlag) {
        classNode = node;
        classResolve = resolve;
        return resolve([]);
    }
    if (node.level === 0) {
        let data = await getGoodsClassListHook({ page: 1, perPage: 999 });
        const list = data.list.map(item => ({ ...item }));
        resolve(list);
        return;
    }
    const id = node.data.id;
    classChildParams.classIds = [id];
    const childList = await getGoodsClassChildListHook(id);
    classChildRequestSuccess[id] = childList[0].id;
    resolve(childList);
};

const classVisibleChangeHandle = async visible => {
    classRequestFlag = false;
    if (visible && classNode.childNodes.length === 0) {
        classLoadHandle(classNode, classResolve);
    }
};
// 展开
const classNodeExpandHandle = (data, node) => {
    if (classChildRequestSuccess[data.id]) return;
    node.loaded = false;
    node.expand();
};
/******************************* 商品类目-end  *******************************/

/******************************* 商品分组-start  *******************************/

const categoryChildRequestSuccess = {};
const categoryChildParams = {
    categoryIds: []
};
let categoryNode = null;
let categoryResolve = null;
let categoryRequestFlag = true;
const categoryLoadHandle = async (node, resolve) => {
    if (categoryRequestFlag) {
        categoryNode = node;
        categoryResolve = resolve;
        return resolve([]);
    }
    if (node.level === 0) {
        let data = await getGoodsCategoryListHook({ page: 1, perPage: 999 });
        const list = data.list.map(item => ({ ...item, disabled: item.hasChildren }));
        resolve(list);
        return;
    }
    const id = node.data.id;
    categoryChildParams.categoryIds = [id];
    const childList = await getGoodsCategoryChildListHook(id);
    categoryChildRequestSuccess[id] = childList[0].id;
    resolve(childList);
};

const categoryVisibleChangeHandle = async visible => {
    categoryRequestFlag = false;
    if (visible && categoryNode.childNodes.length === 0) {
        categoryLoadHandle(categoryNode, categoryResolve);
    }
};
// 展开
const categoryNodeExpandHandle = (data, node) => {
    if (categoryChildRequestSuccess[data.id]) return;
    node.loaded = false;
    node.expand(); // 主动调用展开节点方法，重新查询该节点下的所有子节点
};
/******************************* 商品分组-end  *******************************/

const categoryTreeSelectRef = ref(null);
const validate = () => {
    return new Promise((resolve, reject) => {
        formRef.value.validate(res => {
            if (res) {
                formData.goodsCategoryId = formData.category.map(id => {
                    const obj = formData.categoryCacheData.find(item => item.id === id);
                    const categoryParentId = obj ? obj.parentId : categoryTreeSelectRef.value.getNode(id).data.parentId;
                    const categorySonId = id;
                    return { categoryParentId, categorySonId };
                });
                resolve();
            } else {
                reject();
            }
        });
    });
};
const echoHandle = query => {
    Object.keys(formData).forEach(key => (formData[key] = query[key]));
};
defineExpose({
    echoHandle,
    validate,
    formData
});
</script>

<style lang="scss" scoped>
.upload_list {
    display: flex;
    flex-wrap: wrap;
    column-gap: 16px;
    row-gap: 16px;
    transition: all 0.5s;
}
.el-form-item {
    &:last-child {
        margin-bottom: 0;
    }
    .el-input,
    .el-select {
        width: 600px !important;
    }
}
.form_item_upload_img > :deep(.el-form-item__content) {
    display: block;
    .desc {
        margin-top: 8px;
        font-size: 12px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #969696;
        line-height: 18px;
    }
}
</style>
